package models

import (
	"encoding/json"
	"golang-blog/infrastructure/databases"
	"time"

	"gorm.io/gorm"
)

// 文章类别：多级类别

type Category struct {
	ID             int    `gorm:"primary_key,auto_increment" json:"id"`
	CategoryName   string `gorm:"type:varchar(255);not null;uniqueIndex" json:"category_name"` // 分类名
	Description    string `json:"descrtiption"`                  // 分类描述
	ParentCategory string `json:"parent_category"`               // 父类别，允许为空，其为顶级类别
	CreatedAt      string `json:"create_at"`
	UpdatedAt      string `json:"updated_at"`
	DeletedAt      string `json:"deleted_at"`
}

func (ci *Category) String() string {
	a, _ := json.MarshalIndent(ci, "", "  ")
	return string(a)
}
func (a *Category) BeforeCreate(tx *gorm.DB) (err error) {
	a.CreatedAt = time.Now().Format("2006-01-02 15:04:05")
	a.UpdatedAt = a.CreatedAt
	return
}

func (a *Category) BeforeUpdate(tx *gorm.DB) (err error) {
	a.UpdatedAt = time.Now().Format("2006-01-02 15:04:05")
	return
}
func (a *Category) BeforeDelete(tx *gorm.DB) (err error) {
	a.DeletedAt = time.Now().Format("2006-01-02 15:04:05")
	return
}

//

type Categorys struct {
	wheres Category
	Arts   []Category
	txn    *gorm.DB
}

func NewCategory(tx *gorm.DB) *Categorys {
	if tx == nil {
		tx = databases.GetDB()
	}
	return &Categorys{
		txn:  tx,
		Arts: make([]Category, 1, 32),
	}
}

func (a *Categorys) With(c *Category) *Categorys {
	a.Arts[0] = *c
	return a
}
func (as *Categorys) Where(a *Category) *Categorys {
	as.wheres = *a
	return as
}
func (as *Categorys) FirstOrCreate() (*Category, error) {
	txn := as.txn.Debug().Where(&as.wheres).Attrs(&as.Arts)
	if err := txn.FirstOrCreate(&as.Arts[0]).Error; err != nil {
		return nil, err
	}
	return &as.Arts[0], nil
}
func (as *Categorys) Create() error {
	txn := as.txn.Debug().Model(&Category{})
	if err := txn.Create(&as.Arts).Error; err != nil {
		return err
	}
	return nil
}
func (as *Categorys) First() (*Category, error) {
	txn := as.txn.Debug().Model(&Category{}).Where(&as.wheres)
	if err := txn.First(&as.Arts).Error; err != nil {
		return nil, err
	}
	return &as.Arts[0], nil
}
func (a *Categorys) QueryRange(page, pageSize int) (*[]Category, int, int, error) {
	var (
		count     int64
		totalPage int
	)
	txn := a.txn.Debug().Model(&Category{}).Where(&a.wheres)
	if err := txn.Order("id").Offset((page - 1) * pageSize).Limit(pageSize).Find(&a.Arts).Error; err != nil {
		return nil, 0, 0, err
	}
	if err := txn.Count(&count).Error; err != nil {
		return nil, 0, 0, err
	}
	if int(count)%pageSize != 0 {
		totalPage = int(count)/pageSize + 1
	} else {
		totalPage = int(count) / pageSize
	}
	return &a.Arts, len((*a).Arts), totalPage, nil
}
func (a *Categorys) Update() error {
	txn := a.txn.Debug().Model(&Category{}).Where(&a.wheres)
	if err := txn.Updates(&a.Arts[0]).Error; err != nil {
		return err
	}
	return nil
}
func (a *Categorys) Delete() error {
	txn := a.txn.Debug().Model(&Category{}).Where(&a.wheres)
	if err := txn.Delete(&a.Arts).Error; err != nil {
		return err
	}
	return nil
}
func (a *Categorys) Counts() (int64, error) {
	var count int64
	txn := a.txn.Debug().Model(&Category{}).Where(&a.wheres)
	if err := txn.Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

func (a *Categorys) Last() (*Category, error) {
	txn := a.txn.Debug().Model(&Category{}).Where(&a.wheres)
	if err := txn.Last(&a.Arts).Error; err != nil {
		return nil, err
	}
	return &a.Arts[0], nil
}
